package cn.topcodes.tcsf.admin.web.security;

import cn.topcodes.tcsf.admin.service.security.Resource;
import cn.topcodes.tcsf.admin.service.security.SecurityService;
import com.google.common.base.Strings;
import org.apache.shiro.config.Ini;
import org.apache.shiro.config.Ini.Section;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ChainDefinitionSectionMetaSource implements FactoryBean<Ini.Section> {
	
	public static final String PREMISSION_STRING = "perms[\"{0}\"]";
	public static final String ROLE_STRING = "roles[{0}]";
	
	private String filterChainDefinitions;
	
	@Autowired
	private SecurityService securityService;
	
	public String getFilterChainDefinitions() {
		return filterChainDefinitions;
	}

	public void setFilterChainDefinitions(String filterChainDefinitions) {
		this.filterChainDefinitions = filterChainDefinitions;
	}

	@Override
	public Section getObject() throws Exception {
		Ini ini = new Ini();
		ini.load(filterChainDefinitions);
		Ini.Section section = ini.getSection(Ini.DEFAULT_SECTION_NAME);
		initSection(section);
		section.put("/admin/**", "roles[Developer]");
		return section;
	}

	@Override
	public Class<?> getObjectType() {
		return this.getClass();
	}

	@Override
	public boolean isSingleton() {
		return true;
	}
	
	public void initSection(Ini.Section section) {
		List<Resource> list = this.securityService.findPermDef();
		Map<String,List<String>> map = new HashMap<String,List<String>>();
		for(Resource def : list) {
			if(!Strings.isNullOrEmpty(def.getUrl()) && !Strings.isNullOrEmpty(def.getCode())) {
				if(map.containsKey(def.getUrl())) {
					List<String> values = map.get(def.getUrl());
					if(values != null) {
						values.add(def.getCode());
						continue;
					}
				}
				List<String> values = new ArrayList<String>();
				values.add(def.getCode());
				map.put(def.getUrl(),values);
			}
		}
		for(Map.Entry<String,List<String>> entry : map.entrySet()) {
			String url = entry.getKey();
			String perms = array2String(entry.getValue());
			section.put(url, MessageFormat.format(PREMISSION_STRING, perms));
		}
	}

	private String array2String(List<String> list) {
		StringBuilder sb = new StringBuilder();
		for(int i = 0 ; i < list.size() ; i ++ ) {
			sb.append(list.get(i));
			if(i != list.size() - 1) {
				sb.append(",");
			}
		}
		return sb.toString();
	}
}
